package com.travelgroup.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.travelgroup.constant.FormatConstant;
import com.travelgroup.constant.RedisConstant;
import com.travelgroup.domain.dto.RouteDTO;
import com.travelgroup.domain.dto.RouteLocationDTO;
import com.travelgroup.domain.entity.RouteLocation;
import com.travelgroup.domain.entity.TourRoute;
import com.travelgroup.exception.BusinessException;
import com.travelgroup.exception.R;
import com.travelgroup.mapper.TourRouteMapper;
import com.travelgroup.service.IRouteLocationService;
import com.travelgroup.service.ITourRouterService;
import com.travelgroup.utils.RedisUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class TourRouteServiceImpl extends ServiceImpl<TourRouteMapper, TourRoute>
        implements ITourRouterService {
    @Resource
    private IRouteLocationService routeLocationService;
    @Resource
    private RedisUtil redisUtil;

    /**
     * 创建路线模板
     * @param routeDTO
     * @return
     */
    @Override
    @Transactional
    public R<Long> createTourRouter(RouteDTO routeDTO) {
        // 创建路线模板并存储
        TourRoute tourRoute = new TourRoute();
        BeanUtil.copyProperties(routeDTO, tourRoute);
        if (!save(tourRoute)) {
            log.error("路线存储失败: {}", routeDTO);
            return R.error("路线存储失败");
        }
        Long tourId = tourRoute.getId();

        // 路线所经地点进行存储
        routeLocationService.saveRouteLocation(routeDTO, tourId);
        redisUtil.removeById(RedisConstant.ROUTE_KEY, tourId);

        return R.success("路线创建成功", tourId);
    }

    /**
     * 根据id获取路线模板
     * @param id
     * @return
     */
    @Override
    public R<RouteDTO> queryTourRouteById(Long id) {
        // 获取路线信息
        TourRoute tourRoute = redisUtil.queryById(RedisConstant.ROUTE_KEY, id, TourRoute.class,
                this::getById, RedisConstant.CACHE_TTL, TimeUnit.MINUTES);
        if (tourRoute == null) {
            throw new BusinessException("路线不存在");
        }
        RouteDTO routeDTO = BeanUtil.copyProperties(tourRoute, RouteDTO.class);

        // 获取路线经过地点信息
        List<RouteLocation> routeLocations = redisUtil.queryListById(RedisConstant.ROUTE_LOCATION_KEY, id, RouteLocation.class,
                i -> routeLocationService.lambdaQuery()
                        .eq(RouteLocation::getRouteId, i)
                        .list(), RedisConstant.CACHE_TTL, TimeUnit.MINUTES);
        List<RouteLocationDTO> routeLocationDTOList = routeLocations.stream()
                .map(r -> BeanUtil.copyProperties(r, RouteLocationDTO.class))
                .toList();
        routeDTO.setRouteLocations(routeLocationDTOList);

        return R.success("查询成功", routeDTO);
    }

    /**
     * 更新路线
     * @param id
     * @param routeDTO
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<RouteDTO> updateTourRoute(Long id, RouteDTO routeDTO) {
        // 获取并更新路线信息
        TourRoute tourRoute = redisUtil.queryById(RedisConstant.ROUTE_KEY, id, TourRoute.class,
                this::getById, RedisConstant.CACHE_TTL, TimeUnit.MINUTES);
        if (tourRoute == null) {
            throw new BusinessException("路线不存在或已删除");
        }
        BeanUtil.copyProperties(routeDTO, tourRoute);
        if (!updateById(tourRoute)) {
            throw new BusinessException("路线更新失败");
        }
        redisUtil.removeById(RedisConstant.ROUTE_KEY, id);

        // 删除旧有途径地点
        boolean isSuccess = routeLocationService.lambdaUpdate()
                .eq(RouteLocation::getRouteId, id)
                .remove();
        if (!isSuccess) {
            throw new BusinessException("删除旧途径失败");
        }
        routeLocationService.saveRouteLocation(routeDTO, tourRoute.getId());

        return R.success("数据更新成功", routeDTO);
    }

    /**
     * 删除路线模板
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public R<?> deleteTourRoute(Long id) {
        // 判断路线是否存在
        if (!this.lambdaQuery()
                .eq(TourRoute::getId, id)
                .exists()) {
            return R.error("路线不存在");
        }
        // 若存在，进行删除
        if (!this.removeById(id)) {
            return R.error("数据删除失败");
        }

        // 删除路线途径地点
        boolean locationsDeleted = routeLocationService.lambdaUpdate()
                .eq(RouteLocation::getRouteId, id)
                .remove();

        if (!locationsDeleted) {
            throw new BusinessException("删除途径地点失败");
        }
        redisUtil.removeById(RedisConstant.ROUTE_LOCATION_KEY, id);

        return R.success("路线删除成功", null);
    }

    /**
     * 获取用户创建模板
     * @param userId
     * @param current
     * @return
     */
    @Override
    public R<List<TourRoute>> queryTourRoutesByUserId(Long userId, Integer current) {
        Page<TourRoute> page = this.lambdaQuery()
                .eq(TourRoute::getCreatedBy, userId)
                .page(new Page<>(current, FormatConstant.PAGE_SIZE));

        List<TourRoute> routes = page.getRecords();

        return R.success("查询用户路线成功", routes);
    }

    // TODO 根据组团信息推荐路线模板
}
